package com.buddy.qreport.datasource.dynamic;

import com.alibaba.druid.pool.DruidDataSource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import org.springframework.stereotype.Component;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;

/**
 * 动态数据源
 * 集成到其他项目中时，spring.datasource.type配置为当前类即可
 */
@Slf4j
@Component("dataSource")
public class DynamicDataSource extends AbstractRoutingDataSource {


    private static Map<Object, Object> dataSourceMap = new HashMap<>();


    /**
     *
     * @param dataSourceProperties
     * @param defaultDataSource
     */
    public DynamicDataSource(@Autowired(required = false) DataSourceProperties dataSourceProperties, @Autowired(required = false) @Qualifier("defaultDataSource") DataSource defaultDataSource) {

        //添加默认数据源,用于自身服务数据维护
        //其他数据源等spring初始化完毕后再加入动态数据源中


        //如果默认数据源不为空则注入默认数据源，兼容一下其他途径注入的dataSource
        if (defaultDataSource == null) {

            //如果没有注入默认数据源，就尝试使用配置参数创建一个数据源

            DruidDataSource backupDefaultDataSource = new DruidDataSource();

            defaultDataSource = backupDefaultDataSource;

            if (dataSourceProperties != null) {

                backupDefaultDataSource.setUrl(dataSourceProperties.getUrl());

                backupDefaultDataSource.setUsername(dataSourceProperties.getUsername());

                backupDefaultDataSource.setPassword(dataSourceProperties.getPassword());

                backupDefaultDataSource.setDriverClassName(dataSourceProperties.getDriverClassName());

            } else {

                throw new IllegalArgumentException("数据源参数未注入");
            }


        }


        this.setDefaultDataSource(defaultDataSource);

        log.info("基础数据源初始化完成");
    }


    @Override
    public void afterPropertiesSet() {
        //

        if (dataSourceMap.get(DataSourceContextHolder.DEFAULT_DATASOURCE_ID) == null) {

            throw new IllegalStateException("默认数据源未设置");
        }

    }

    public boolean avaiable(String id) {

        if (dataSourceMap.containsKey(id)) {

            DruidDataSource dataSource = (DruidDataSource) dataSourceMap.get(id);

            return dataSource.isEnable();

        }

        return false;
    }

    public void addDataSource(String id, DataSource dataSource) {

        if (DataSourceContextHolder.DEFAULT_DATASOURCE_ID.equals(id)) {

            if (dataSourceMap.containsKey(DataSourceContextHolder.DEFAULT_DATASOURCE_ID)) {

                logger.warn("默认数据源已存在,当前操作忽略");
                // throw new IllegalArgumentException("默认数据源已存在");
            }
        }

        this.remove(id);
        dataSourceMap.put(id, dataSource);

    }

    public void remove(String id) {

        if (dataSourceMap.containsKey(id)) {

            DataSource dataSource = (DataSource) dataSourceMap.remove(id);

            if (dataSource != null & dataSource instanceof DruidDataSource) {

                ((DruidDataSource) dataSource).close();
            }

        }

    }

    public void setDefaultDataSource(DataSource defaultDataSource) {

        dataSourceMap.put(DataSourceContextHolder.DEFAULT_DATASOURCE_ID, defaultDataSource);

    }

    @Override
    protected Object determineCurrentLookupKey() {

        return dataSourceMap.get(DataSourceContextHolder.getDataSourceId());
    }

    @Override
    protected DataSource determineTargetDataSource() {
        return (DataSource) determineCurrentLookupKey();
    }

}
